// Maciej Chałapuk (maciej@chalapuk.pl)
// vim: ts=2 sw=2 expandtab

#ifndef STATIC_FOR_HPP
#define STATIC_FOR_HPP

#include <type_traits>
#include <cstddef>
#include <functional>
#include <iostream>

namespace experiment {


template <
  size_t size,
  size_t i = 0
  >
struct static_loop {
  static_assert(size >= 1, "size < 1");

  template <class function>
  static void run(function f) {
    constexpr size_t half = size/2;
    static_loop<half, i>::run(f);
    static_loop<size-half, i+half>::run(f);
  }
};

template <size_t i>
struct static_loop<size_t(1), i> {
  template <class function>
  static void run(function f) {
    f(i);
  }
};


template <
  size_t size,
  size_t i = 0,
  class function
  >
inline void static_for(function f) {
  static_loop<size, i>::run(f);
}


} // namespace experiment


#endif // include guard

